import json
import re
from pathlib import Path

from loguru import logger

from sw2py import template


class Swagger(object):
    def __init__(self, path, conf=None):
        self.body = self.load_swagger(path)
        self.path = path
        self.conf = conf

    @staticmethod
    def definitions(body: dict, test_dir):
        definition = body['definitions']

        pathname = Path(test_dir, 'fixtures', 'definitions')
        pathname.is_dir() or pathname.mkdir(parents=True)

        for k, v in definition.items():
            filename = str(k)
            filename = Path(pathname, f'{filename}.json')

            with open(filename, 'w') as fp:
                json.dump(v, fp, ensure_ascii=False)
                logger.warning(filename)

    def export(self, test_dir, sub_path):

        base = Path(test_dir, sub_path, 'base.py')
        module = '.'.join([test_dir, sub_path])

        # gen definitions
        self.definitions(self.body, test_dir)

        Path(base).parent.is_dir() or Path(base).parent.mkdir(parents=True)

        if not Path(base).is_file():
            content = template.Template(template_name='base.j2', context={})
            Path(base).write_text(content)

        for item, value in self.body['paths'].items():

            for method, schema in self.body['paths'][item].items():

                if 'parameters' in method:
                    continue

                pathname = re.sub(r'\/\{\w+\}', '', item.strip('/')).split('/')
                filename = class_name = pathname.pop(-1)
                filename = Path(test_dir, sub_path, *pathname, f"test_{filename}.py")

                result = {
                    'class_name': class_name.capitalize(),
                    'module': module,
                    'function': schema['operationId'],
                    'filename': str(filename),

                    'submit': 'data' if True else 'json',
                    'method': method,
                    'parent_parameters': value.get('parameters'),
                }

                result.update(schema)

                # todo
                Path(filename).parent.is_dir() or Path(filename).parent.mkdir(parents=True)

                if not Path(filename).is_file():
                    content = template.Template(template_name='test.j2', context=result)
                    Path(filename).write_text(content)

                # todo
                content = Path(filename).read_text()

                if result['function'] in content:
                    logger.warning(f"{filename} 包含 {result['function']} skip.")
                    continue

                with open(filename, 'a+') as fp:
                    fp.write(template.Template(template_name='case.j2', context=result))

                logger.info(result)

    @staticmethod
    def load_swagger(path):
        with open(path, encoding='UTF-8') as fp:
            return json.load(fp)


def get_api_param(item):
    if 'parameters' in item:
        return list(item['parameters'])

    return []
